package org.elec.mac.gizwits;

import org.elec.mac.constants.Constants;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

/**
 * Created by Bean on 2018/6/2.
 */
@Slf4j
@Component
public class GizWebSocketListener extends WebSocketListener {

    @Autowired
    private GizApi gizApi;

    @Value("${giz.login.header}")
    private String appId;

    @Value("${giz.login.username}")
    private String username;

    @Value("${giz.login.password}")
    private String password;

    @Override
    public void onOpen(WebSocket webSocket, Response response) {
        log.info("Giz WebSocket Open");
        boolean bool = gizApi.wsLogin(webSocket, appId, Constants.gizToken);
        log.info("Giz WebSocket Login Send : " + bool);
    }

    @Override
    public void onMessage(WebSocket webSocket, String text) {
        String status;
        String did;

        //log.info("Giz WebSocket Message : " + text);

        JSONObject jsonObject = new JSONObject(text);
        String cmd = jsonObject.getString("cmd");

        JSONObject data = null;
        try {
            data = jsonObject.getJSONObject("data");
        } catch (JSONException ignored) {
        }

        //log.info("cmd : " + cmd);
        switch (cmd) {
            //登录响应
            case "login_res":
                if (data.getBoolean("success")) {
                    log.info("Giz webSocket登录成功");
                    Constants.webSocket = webSocket;
                } else {
                    log.error("Giz webSocket登录失败");
                }
                break;
            //订阅响应
            case "subscribe_res":
                assert data != null;

                JSONArray successArray = data.getJSONArray("success");
                JSONArray failureArray = data.getJSONArray("failed");

                successArray.forEach(o -> log.info("订阅成功 did ： "
                        + new JSONObject(o.toString()).getString("did")));

                failureArray.forEach(o -> {
                    JSONObject errorObj = new JSONObject(o.toString());
                    log.error("订阅失败 did ： "
                            + errorObj.getString("did")
                            + " msg : " + errorObj.getString("msg"));
                });

                break;
            //设备上下线通知
            case "s2c_online_status":
                assert data != null;

                did = data.getString("did");
                String passcode = data.getString("passcode");
                String mac = data.getString("mac");
                boolean online = data.getBoolean("online");
                status = online ? "上线" : "下线";
                log.info("设备did : " + did + " mac : " + mac + " " + status);
                break;
            //设备绑定解绑状态变更通知
            case "s2c_binding_changed":
                assert data != null;

                did = data.getString("did");
                boolean bind = data.getBoolean("bind");
                status = bind ? "绑定" : "解绑";
                log.info("设备did : " + did + " " + status);
                break;
            //读取标准数据点
            case "s2c_noti":
                assert data != null;

                did = data.getString("did");
                log.info("设备标识："+did);
                //数据点键值对
                JSONObject attrs = data.getJSONObject("attrs");
                log.info("读取到数据点");
                for (Object o : attrs.names()) {
                    log.info("key : " + o + " | value : " + attrs.get(String.valueOf(o)));
                }

                break;
            //心跳
            case "pong":
                //log.info("pong");
                break;
            //非法消息
            case "s2c_invalid_msg":
                String errorMsg = data.getString("msg");
                log.error("非法消息 ： " + errorMsg);
                break;
            default:
                log.error("未定义消息");
                break;
        }
    }

    @Override
    public void onMessage(WebSocket webSocket, ByteString bytes) {
    }

    @Override
    public void onClosing(WebSocket webSocket, int code, String reason) {
        log.error("Giz WebSocket onClosing");
    }

    @Override
    public void onClosed(WebSocket webSocket, int code, String reason) {
        log.error("Giz WebSocket onClosed");
    }

    @Override
    public void onFailure(WebSocket webSocket, Throwable t, Response response) {
        log.error("Giz WebSocket onFailure!! t: " + t + " response : " + response);
    }
}
